package com.airsystem.pos.bengkel.service;

import java.math.BigDecimal;
import java.util.Collection;
import java.util.Date;
import java.util.HashSet;
import java.util.LinkedList;
import java.util.List;
import java.util.Set;

import org.hibernate.Criteria;
import org.hibernate.Hibernate;
import org.hibernate.Session;
import org.hibernate.criterion.Order;
import org.hibernate.criterion.Restrictions;

import com.airsystem.pos.bengkel.entity.DetailOrderLayanan;
import com.airsystem.pos.bengkel.entity.DetailOrderLayanan.Metode;
import com.airsystem.pos.bengkel.entity.OrderLayanan;
import com.airsystem.pos.bengkel.entity.wrapper.OrderLayananWrapper;
import com.airsystem.pos.bengkel.util.DateUtil;
import com.airsystem.pos.bengkel.util.HibernateUtil;

/**
 * @author Budi Oktaviyan <budi.oktaviyan@icloud.com>
 */
public class OrderLayananServices {

	public Collection<OrderLayananWrapper> select(OrderLayanan data) {
		Session session = HibernateUtil.getSessionFactory().openSession();
		List<OrderLayanan> orders = null;

		try {
			Criteria criteria = session.createCriteria(OrderLayanan.class);

			if (data.getTanggal() != null) {
				criteria.add(Restrictions.eq("tanggal", data.getTanggal()));
			}
			orders = criteria.addOrder(Order.desc("tanggal")).list();

			for (OrderLayanan item : orders) {
				Hibernate.initialize(item.getDetail_order_layanan());

				for (DetailOrderLayanan detOrder : item.getDetail_order_layanan()) {
					Hibernate.initialize(detOrder.getDetail_sparepart());
				}
			}
		} finally {
			session.close();
		}

		Collection<OrderLayananWrapper> results = new LinkedList<OrderLayananWrapper>();
		for (OrderLayanan source : orders) {
			String tanggalTransaksi = DateUtil.convertDateDisplay(source.getTanggal());
			String pelanggan = source.getDetail_pelanggan().getPelanggan().getNama();

			Set<String> setKendaraan = new HashSet<String>();
			Set<String> setSparepartTerpakai = new HashSet<String>();

			Set<Long> setLayanan = new HashSet<Long>();

			BigDecimal orderTotal = new BigDecimal(0);

			Metode metode = Metode.UNKNOWN;

			for (DetailOrderLayanan item : source.getDetail_order_layanan()) {
				BigDecimal itemCost = new BigDecimal(0);
				BigDecimal itemPrice = new BigDecimal(0);
				BigDecimal oneOrderTotal = new BigDecimal(0);

				String pelangganKendaraan = new StringBuffer(item.getDetail_layanan().getDetail_kendaraan().getKendaraan().getMerk())
												.append(" - ").append(item.getDetail_layanan().getDetail_kendaraan().getSub_merk()).toString();

				setKendaraan.add(pelangganKendaraan);

				if (item.getDetail_sparepart() != null) {
					String sparepartTerpakai = new StringBuffer(item.getDetail_sparepart().getSparepart().getMerk())
												   .append(" - ").append(item.getDetail_sparepart().getSub_merk()).toString();

					setSparepartTerpakai.add(sparepartTerpakai);

					itemPrice = item.getDetail_sparepart().getHarga_satuan();
				}

				if (metode == Metode.UNKNOWN) {
					metode = item.getMetode_e();
				} else if ((metode == Metode.HUTANG_1_MINGGU
					   || 	metode == Metode.HUTANG_2_MINGGU
					   || 	metode == Metode.HUTANG_3_MINGGU
					   || 	metode == Metode.HUTANG_4_MINGGU && item.getMetode_e() == Metode.TUNAI)
					   ||  (metode == Metode.TUNAI && item.getMetode_e() == Metode.HUTANG_1_MINGGU
					   							   || item.getMetode_e() == Metode.HUTANG_2_MINGGU
					   							   || item.getMetode_e() == Metode.HUTANG_3_MINGGU
					   							   || item.getMetode_e() == Metode.HUTANG_4_MINGGU)) {
					metode = Metode.BOTH;
				}

				setLayanan.add(item.getDetail_layanan().getLayanan().getId());

				itemCost = itemPrice.multiply(new BigDecimal(item.getSparepartTerpakai()));

				oneOrderTotal = oneOrderTotal.add(itemCost);
				oneOrderTotal = oneOrderTotal.add(item.getDetail_layanan().getHarga());

				orderTotal = orderTotal.add(oneOrderTotal);
			}

			int totalKendaraan = setKendaraan.size();
			int totalSparepart = setSparepartTerpakai.size();
			int totalLayanan = setLayanan.size();

			OrderLayananWrapper target = new OrderLayananWrapper(source, tanggalTransaksi, pelanggan, totalKendaraan, totalSparepart, totalLayanan, orderTotal, metode);
			results.add(target);
		}

		return results;
	}

	public void saveOrUpdate(OrderLayanan data) {
		Session session = HibernateUtil.getSessionFactory().openSession();

		try {
			session.saveOrUpdate(data);

			for (DetailOrderLayanan child : data.getDetail_order_layanan()) {
				session.save(child);
			}
		} finally {
			session.close();
		}
	}

	public void delete(DetailOrderLayanan detailOrderLayanan) {
		Session session = HibernateUtil.getSessionFactory().openSession();

		try {
			session.delete(detailOrderLayanan);
		} finally {
			session.close();
		}
	}

	public List<DetailOrderLayanan> transactionPrint(Long ID, Date tanggal) {
		Session session = HibernateUtil.getSessionFactory().openSession();

		Criteria criteria = session.createCriteria(DetailOrderLayanan.class);
		Criteria subCriteria = criteria.createCriteria("order_layanan");
		subCriteria.add(Restrictions.eq("id", ID));
		subCriteria.add(Restrictions.eq("tanggal", tanggal));

		List result = criteria.list();
		session.close();

		return result;
	}

	public List<DetailOrderLayanan> print(Date start, Date end, Integer metode) throws Exception {
		Session session = HibernateUtil.getSessionFactory().openSession();

		Criteria criteria = session.createCriteria(DetailOrderLayanan.class);
		Criteria subCriteria = criteria.createCriteria("order_layanan");
		subCriteria.add(Restrictions.between("tanggal", start, end));

		if (metode != 5) {
			switch (metode) {
			case 0:
				criteria.add(Restrictions.like("metode", 0));
				break;
			case 1:
				criteria.add(Restrictions.like("metode", 1));
				break;
			case 2:
				criteria.add(Restrictions.like("metode", 2));
				break;
			case 3:
				criteria.add(Restrictions.like("metode", 3));
				break;
			case 4:
				criteria.add(Restrictions.like("metode", 4));
				break;
			}
		}

		List result = criteria.list();
		session.close();

		return result;
	}
}